package search

import (
	"context"
	"strconv"
	"strings"

	"mall/common/ctxdatax"
	"mall/common/enumx"
	"mall/common/resultx"
	"mall/service/blog/rpc/blogclient"
	"mall/service/forum/api/internal/svc"
	"mall/service/forum/api/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type BasicSearchLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewBasicSearchLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BasicSearchLogic {
	return &BasicSearchLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *BasicSearchLogic) BasicSearch(req *types.BasicSearchReq, ip string) (resp *types.BasicSearchResp, err error) {
	// logx.Infof("BasicSearchReq : %+v ", req)
	search := strings.TrimSpace(req.Search)
	if len(search) == 0 {
		return nil, resultx.NewErrCode(resultx.ENTRY_NO_SEARCH_TERM_SPECIFIED)
	}

	var page int64 = 1
	var pageSize int64
	if req.Current > 1 {
		page = req.Current
	}
	if req.PageSize > 0 { // 指定，检查最大值
		pageSize = req.PageSize
		if pageSize > l.svcCtx.Config.Query.MaxAmount {
			pageSize = l.svcCtx.Config.Query.MaxAmount
		}
	} else { // 不指定，使用默认值
		pageSize = l.svcCtx.Config.Query.DefaultAmount
	}

	var filter string
	reqWith := strings.TrimSpace(req.With)
	if len(reqWith) > 0 {
		filter = reqWith
	}

	var preFilter string
	reqFilter := strings.TrimSpace(req.Filter)
	if len(reqFilter) > 0 {
		preFilter = reqFilter
	}

	var sorter string
	reqSorter := strings.TrimSpace(req.Sorter)
	if len(reqSorter) > 0 {
		sorter = reqSorter
	}
	userId := ctxdatax.GetUserId(l.ctx)
	platformId := int32(enumx.ThirdPartyPlatformWechatMini)
	res, err := l.svcCtx.BlogRpc.BasicSearch(l.ctx, &blogclient.BasicSearchReq{
		Offset:     int32((page-1)*pageSize),
		Limit:      int32(pageSize),
		Preload:    "blogBook:Id,Title,Slug;blogMedia:Uid,Id,Url,Thumbnail,Order;blogBookRelation:brand",
		EagerLoad:  "blogBook:blogMedia,blogTerm,blogBookRelation",
		Filter:     filter,
		Sorter:     sorter,
		PreFilter:  preFilter,
		Search:     search,
		VisitorId:  int64(userId),
		PlatformId: platformId,
	})
	if err != nil {
		return nil, err
	}

	list := l.parseList(res.PerfumeList)
	if res.Offset > 0 {
		page = int64(res.Offset) / pageSize
		page += 1
	}

	return &types.BasicSearchResp{
		Current:         page,
		PageSize:        pageSize,
		List:            list,
		HasNextPage:     res.HasNextPage > 0,
		HasPreviousPage: res.HasPreviousPage > 0,
		SearchId:        res.SearchLogId,
	}, nil
}

func (l *BasicSearchLogic) parseList(data []*blogclient.BookDetailResp) ([]*types.PerfumeInfo) {
	var list []*types.PerfumeInfo
	if len(data) > 0 {
		for _, item := range data {
			var sections []*types.ForumCategory
			if len(item.Sections) > 0 {
				for _, s := range item.Sections {
					sections = append(sections, &types.ForumCategory{
						Id:    s.Id,
						Name:  s.Name,
						Slug:  s.Slug,
						Alias: s.Uri,
					})
				}
			}
			var media []*types.ForumMedia
			if len(item.Media) > 0 {
				for _, m := range item.Media {
					media = append(media, &types.ForumMedia{
						Uid:       m.Uid,
						Id:        m.Id,
						Url:       m.Url,
						Thumbnail: m.Thumbnail > 0,
						Order:     m.Order,
					})
				}
			}
			var brand []*types.PerfumeInfo
			var perfume []*types.PerfumeInfo
			var nose []*types.PerfumeInfo
			var group []*types.PerfumeInfo
			var topNote []*types.PerfumeInfo
			var heartNote []*types.PerfumeInfo
			var baseNote []*types.PerfumeInfo
			if len(item.Relations) > 0 {
				for _, r := range item.Relations {
					switch r.Section {
					case "brand":
						brand = append(brand, &types.PerfumeInfo{
							Id:    r.Id,
							Title: r.Title,
							Slug:  r.Slug,
						})
					case "perfume":
						perfume = append(perfume, &types.PerfumeInfo{
							Id:    r.Id,
							Title: r.Title,
							Slug:  r.Slug,
						})
					case "nose":
						nose = append(nose, &types.PerfumeInfo{
							Id:    r.Id,
							Title: r.Title,
							Slug:  r.Slug,
						})
					case "group":
						group = append(group, &types.PerfumeInfo{
							Id:    r.Id,
							Title: r.Title,
							Slug:  r.Slug,
						})
					case "note":
						switch r.GroupId {
						case 1:
							topNote = append(topNote, &types.PerfumeInfo{
								Id:    r.Id,
								Title: r.Title,
								Slug:  r.Slug,
							})
						case 2:
							heartNote = append(heartNote, &types.PerfumeInfo{
								Id:    r.Id,
								Title: r.Title,
								Slug:  r.Slug,
							})
						case 3:
							baseNote = append(baseNote, &types.PerfumeInfo{
								Id:    r.Id,
								Title: r.Title,
								Slug:  r.Slug,
							})
						}
					}
				}
			}

			var year string
			if item.Order > 1500 {
				year = strconv.FormatInt(item.Order, 10)
			}
			list = append(list, &types.PerfumeInfo{
				Id:            item.Id,
				Title:         item.Title,
				Slug:          item.Slug,
				Excerpt:       item.Excerpt,
				CommentStatus: item.CommentStatus > 0,
				CommentCount:  item.CommentCount,
				Year:          year,
				Section:       sections,
				Media:         media,
				Brand:         brand,
				Perfume:       perfume,
				Nose:          nose,
				Group:         group,
				TopNote:       topNote,
				HeartNote:     heartNote,
				BaseNote:      baseNote,
			})
		}
	}
	
	return list
}
